package com.mall.config

import com.mall.security.JwtAuthenticationFilter
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter

/**
 * Spring Security 配置类
 * 
 * 该类负责配置项目的安全相关设置，包括：
 * 1. 认证和授权规则
 * 2. 密码加密方式
 * 3. JWT Token过滤器配置
 * 4. 会话管理策略
 * 
 * @property jwtAuthenticationFilter JWT认证过滤器，用于处理Token的验证
 */
@Configuration
@EnableWebSecurity
class SecurityConfig(private val jwtAuthenticationFilter: JwtAuthenticationFilter) {

    /**
     * 配置Spring Security的安全过滤链
     * 
     * @param http HttpSecurity对象，用于配置安全规则
     * @return SecurityFilterChain 配置好的安全过滤链
     * 
     * 主要配置说明：
     * 1. 禁用CSRF防护（因为使用JWT进行认证）
     * 2. 使用无状态会话管理（JWT模式不需要服务端存储会话）
     * 3. 配置URL访问权限：
     *    - 登录、注册接口和Swagger文档接口允许匿名访问
     *    - 管理员和商品相关接口需要认证后访问
     *    - 其他所有请求都需要认证
     * 4. 添加JWT认证过滤器到UsernamePasswordAuthenticationFilter之前
     */
    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http
            .csrf { csrf -> csrf.disable() }
            .sessionManagement { session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) }
            .authorizeHttpRequests { auth -> auth
                .requestMatchers("/api/admin/login", "/api/admin/register", "/swagger-ui/**", "/swagger-ui.html", "/swagger-resources/**", "/v3/api-docs/**", "/api-docs/**").permitAll()
                .requestMatchers("/api/admin/**", "/api/product/**").authenticated()
                .anyRequest().authenticated()
            }
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter::class.java)

        return http.build()
    }

    /**
     * 配置密码编码器
     * 
     * @return PasswordEncoder BCrypt密码编码器实例
     * 
     * 使用BCrypt加密算法对密码进行加密，该算法具有以下特点：
     * 1. 自动生成随机盐值
     * 2. 可配置加密强度
     * 3. 不可逆加密
     * 4. 自适应单向函数
     */
    @Bean
    fun passwordEncoder(): PasswordEncoder {
        return BCryptPasswordEncoder()
    }
}